//
//  Manathan.cpp
//  Taquin
//
//  Created by Benjamin Bouachour on 13/08/11.
//  Copyright 2011 Epitech. All rights reserved.
//

#include "Manathan.h"
#include <math.h>


Manathan::Manathan()
{}

Manathan::Manathan(const Etat *_final) : final(*_final)
{
}

Manathan::Manathan(const Manathan &copie)
{   
    this->final = copie.final;
}

IHeuristique::~IHeuristique()
{}

Manathan::~Manathan()
{
}

const int Manathan::calculGCost(const Etat *parent, Etat *etat)
{
	if (parent != NULL)
	    etat->setCost(parent->getCost() +1);
	else
		etat->setCost(0);
    return etat->getCost();
}


//const int Manathan::calculHCost(Etat *etat)
//{
//    
//    // Manahttan
//    
//    
//    // Remplacer dans le code les t_grid en map<string, pair<int, int > >
//    // pour chaque element de la grille chercher son homologue dans le final
//    // calculer la distance du noeud : manahattan
//    // ajout à la distance finale
//    // retourner distance finale
//    int res = 0;
//    const tgrid currentGrid = etat->getGrid();
//    invert_tgrid final_invertTgrid = exchangeGrid(final.getGrid());
//    for (tgrid::const_iterator it = currentGrid.begin(); it != currentGrid.end(); ++it)
//    {
//        string finae = it->second;
//        pair<int, int> coord_f = final_invertTgrid[it->second];
//        pair<int, int> coord_v = it->first;
////        int tmp = pow(coord_f.first - coord_v.first, 2) + pow(coord_f.second - coord_v.second, 2);        
////        if (tmp == 0)
////            res -= 1;
////        else
////            res += tmp;
//        res += fabs(coord_f.first - coord_v.first) + fabs(coord_f.second - coord_v.second);
//    }
//    cout << "Hcost return " << res << endl;
//    etat->setDistance(res);
//    return res;
//}


const int Manathan::calculHCost(Etat *etat)
{
      //miss placed
////    AffResult aff;
//    int res = 0;
//    const tgrid currentGrid = etat->getGrid();
//    invert_tgrid final_invertTgrid = exchangeGrid(final.getGrid());
//    for (tgrid::const_iterator it = currentGrid.begin(); it != currentGrid.end(); ++it)
//    {
//        pair<int, int> coord_f = final_invertTgrid[it->second];
//        pair<int, int> coord_v = it->first;
//        if ((coord_f.first - coord_v.first) + (coord_f.second - coord_v.second) != 0)
//            res += 1;
//    }
//    cout << "Hcost return " << res << endl;
//    etat->setDistance(res);
//    return res;   
	return 0;
}

const int Manathan::calculHCost(Etat *parent, Etat *etat)
{
//Minkowski
//    AffResult aff;
    int res = 0;
    const tgrid currentGrid = etat->getGrid();
    int missplaced;
    invert_tgrid final_invertTgrid = exchangeGrid(final.getGrid());
    for (tgrid::const_iterator it = currentGrid.begin(); it != currentGrid.end(); ++it)
    {
        pair<int, int> coord_f = final_invertTgrid[it->second];
        pair<int, int> coord_v = it->first;
  
		res += (abs(coord_f.first - coord_v.first) + abs(coord_f.second - coord_v.second));
    }
    etat->setDistance(res);
    return res;   
}
//

const int Manathan::calculHeuristique(Etat *etat)
{
    etat->setQualite(etat->getCost() + etat->getDistance());
    return etat->getQualite();
    //    cout << "Calcul heuristique" << "" << endl;
    //    tgrid nextGrid = etat->getGrid();
    //    tgrid::iterator it;
    //    int g = 1;
    //    int h = 0;
    //    tgrid *finalGrid = new tgrid(final.getGrid());
    //    int i;
    //    for (it = nextGrid.begin(), i = 0; it != nextGrid.end();  ++i, ++it)
    //    {
    //        cout << "Boucle sur la grid : " << i << endl;
    //        h += calculHCost(it, finalGrid);
    //        cout << "nouveau cout  h : " << h <<  endl;
    //    }
    //    cout << "calcul return :  " <<g+h << endl;
    //    return g+h;
}

invert_tgrid Manathan::exchangeGrid(const tgrid grid)
{
    invert_tgrid res;
    for (tgrid::const_iterator it = grid.begin(); it != grid.end(); ++it)
        res[it->second] = it->first;
    return res;
}

const void Manathan::setCurrent(const Etat *newEtat)
{
    return;
}








//tgrid::iterator it;
//for (it = finalGrid->begin(); it != finalGrid->end(); ++it)
//if (it->second == itNext->second)
//break;
//if (it == finalGrid->end())
//throw new string("value " + itNext->second + " Not found in finalGrid");
///* Algo Heuristique -- Calcul de la distance de manathan*/
//
